/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package br.com.gwbuonny.tstportal.portal.wsdl.incluir_sm;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.Set;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.xml.namespace.QName;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;

/**
 *
 * @author jose.carvalho
 */
public class ServerSOAPHandler implements SOAPHandler<SOAPMessageContext>{

    
    
    /**
     * Is called after constructing the handler and before executing any othe method.
     */
    @PostConstruct
    public void init() {
        
    }


    /**
     * Returns the <code>Set</code> of supported SOAP headers
     */
    public Set<QName> getHeaders() {
        return null;
    }

    /**
     * Returns the message encoding (e.g. utf-8)
     *
     * @param msg
     * @return
     * @throws javax.xml.soap.SOAPException
     */
    private String getMessageEncoding(SOAPMessage msg) throws SOAPException {
        String encoding = "utf-8";
        if (msg.getProperty(SOAPMessage.CHARACTER_SET_ENCODING) != null) {
            encoding = msg.getProperty(SOAPMessage.CHARACTER_SET_ENCODING).toString();
        }
        System.out.println("aaaaaaaa bbbbbbbbbbbb " +msg.toString());
        
        return encoding;
    }


    /**
     * Dump SOAP Message to console
     *
     * @param msg
     */
    private void dumpSOAPMessage(SOAPMessage msg) {
        if (msg == null) {
            System.out.println("SOAP Message is null");
            return;
        }
        System.out.println("");
        System.out.println("--------------------");
        System.out.println("DUMP OF SOAP MESSAGE");
        System.out.println("--------------------");
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            msg.writeTo(baos);
//            setRetornoXML(baos.toString(getMessageEncoding(msg)));
            String retornoStr = baos.toString(getMessageEncoding(msg));
//.replace("xmlns:ns1=\"http://tstportal.buonny.com.br/portal/wsdl/incluir_sm\"", "");
//            retorno = retorno.replace("<viagem_result>", "<viagem_result xmlns=\"http://tstportal.buonny.com.br/portal/wsdl/incluir_sm\">");
            // show included values
            System.out.println("retorno " + retornoStr);
            br.com.gwsistemas.buonny.entidade.Retorno retorno = br.com.gwsistemas.buonny.entidade.Retorno.getInstance();
            retorno.setXml(retornoStr);
            
//            InputStream is = new ByteArrayInputStream(retorno.getBytes());
//            msg = MessageFactory.newInstance().createMessage(null, is);
//            String values = msg.getSOAPBody().getTextContent();
//            System.out.println("Included values:" + values);
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * This method handles the incoming and outgoing SOAP-Message.
     * It's an excellent point to manipulate the SOAP.
     *
     * @param SOAPMessageContext
     * @return boolean
     */
    public boolean handleMessage(SOAPMessageContext context) {
        
        //Inquire incoming or outgoing message.
        boolean outbound = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);

        try {

            if (outbound) {
                // OUTBOUND

                System.out.println("Direction=outbound (handleMessage)");
                SOAPMessage msg = ((SOAPMessageContext) context).getMessage();

                // get SOAP-Part
                SOAPPart sp = msg.getSOAPPart();

                //edit Envelope
                SOAPEnvelope env = sp.getEnvelope();

                // add namespaces
//                env.addNamespaceDeclaration("blog", "http://blog.jdevelop.eu");
//                env.addNamespaceDeclaration("xsd", "http://www.w3.org/2001/XMLSchema");
//                env.addNamespaceDeclaration("xsi", "http://www.w3.org/2001/XMLSchema-instance");
//                env.addNamespaceDeclaration("soap", "http://schemas.xmlsoap.org/soap/envelope");

                // add the Header with additional Elements
//                SOAPElement soapElement1 = env.addHeader().addHeaderElement(new QName("http://blog.jdevelop.eu/securityprotocol", "Security"));
//                soapElement1.addTextNode("1");

//                SOAPElement soapElement2 = env.getHeader().addHeaderElement(new QName("http://blog.jdevelop.eu/securityprotocol", "Compression"));
//                soapElement2.addTextNode("gzip");

//                SOAPElement soapElement3 = env.getHeader().addHeaderElement(new QName("http://blog.jdevelop.eu/securityprotocol", "Username"));
//                soapElement3.addTextNode("jdevelop");

//                SOAPElement soapElement4 = env.getHeader().addHeaderElement(new QName("http://blog.jdevelop.eu/securityprotocol", "Password"));
//                soapElement4.addTextNode("blog");

                // get the SOAP-Body
                SOAPBody body = env.getBody();

                // add an additional Element to the SOAP-Body
//                SOAPBodyElement bodyElement = body.addBodyElement(new QName("http://blog.jdevelop.eu/securitymessage", "message"));
//                bodyElement.addTextNode("Security through obscurity");

                // print SOAP-Message
                dumpSOAPMessage(msg);


            } else {
                // INBOUND

                System.out.println("Direction=inbound (handleMessage)");
                SOAPMessage msg = ((SOAPMessageContext) context).getMessage();
                dumpSOAPMessage(msg);
                

             }

        } catch (Exception e) {

            //All other unhandled problems.
            e.printStackTrace();
        }
        return true;
    }


    /**
     * Handles SOAP-Errors.
     *
     * @param context
     * @return
     */
    public boolean handleFault(SOAPMessageContext context) {
//        System.out.println("ServerSOAPHandler.handleFault");
        boolean outbound = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
        if (outbound) {
            System.out.println("Direction=outbound (handleFault)");
        } else {
            System.out.println("Direction=inbound (handleFault)");
        }
        if (!outbound) {
            try {
                SOAPMessage msg = ((SOAPMessageContext) context).getMessage();
                dumpSOAPMessage(msg);
                if (context.getMessage().getSOAPBody().getFault() != null) {
                    String detailName = null;
                    try {
                        detailName = context.getMessage().getSOAPBody().getFault().getDetail().getFirstChild().getLocalName();
                        System.out.println("detailName=" + detailName);
                    } catch (Exception e) {
                    }
                }
            } catch (SOAPException e) {
                e.printStackTrace();
            }
        }
        return true;
    }


    public void close(MessageContext messageContext) {
//        System.out.println("close");
    }


    /**
     * Is executed before this handler is being destroyed -
     * means after close() has been executed.
     */
    @PreDestroy
    public void destroy() {
//        System.out.println("destroy");
    }
    
    
    
//    private String retornoXML = "";
//
//    private void setRetornoXML(String xmlRetorno) {
//        this.retornoXML = xmlRetorno;
//    }
//    
//    public String getRetornoXML() {
//        return this.retornoXML;
//    }
    
}
